bitkeeper revision 1.1443 (428b3f59xxbCVcbUBrHu1R1TkWcYhg)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 18 May 2005 13:12:57 +0000 (13:12 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 18 May 2005 13:12:57 +0000 (13:12 +0000)
Cleaner GDT interface. Xen now reserves the last 2 pages of a full-size
(16 page) GDT. A guest can register a GDT with up to 7k entries. Xen
automatically makes the GDT up to max size with empty page mappings,
and turns page faults in that area to #GP(selector).
Signed-off-by: Keir Fraser <keir@xensource.com>
28 files changed:
.rootkeys
freebsd-5.3-xen-sparse/i386-xen/i386-xen/machdep.c
freebsd-5.3-xen-sparse/i386-xen/i386-xen/mp_machdep.c
linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c
linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/segment.h
linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/segment.h
netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c
tools/libxc/xc_linux_restore.c
xen/arch/x86/boot/x86_32.S
xen/arch/x86/boot/x86_64.S
xen/arch/x86/dom0_ops.c
xen/arch/x86/domain.c
xen/arch/x86/domain_build.c
xen/arch/x86/mm.c
xen/arch/x86/setup.c
xen/arch/x86/trampoline.S
xen/arch/x86/traps.c
xen/arch/x86/x86_32/seg_fixup.c
xen/arch/x86/x86_32/traps.c
xen/include/asm-x86/config.h
xen/include/asm-x86/desc.h
xen/include/asm-x86/domain.h
xen/include/asm-x86/ldt.h
xen/include/asm-x86/mm.h
xen/include/asm-x86/processor.h
xen/include/asm-x86/x86_64/ldt.h [deleted file]
xen/include/public/arch-x86_32.h
xen/include/public/arch-x86_64.h

index 797542a380fc95086270a650aa8dbfaedc793f85..6a7a851ef8dccd9f5238f97620af4c03869f218e 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 41bf1717bML6GxpclTWJabiaO5W5vg xen/include/asm-x86/x86_64/asm_defns.h
 404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h
 41febc4b1aCGLsm0Y0b_82h7lFtrEA xen/include/asm-x86/x86_64/domain_page.h
-404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h
 4208e2a3Fktw4ZttKdDxbhvTQ6brfQ xen/include/asm-x86/x86_64/page.h
 404f1bb86rAXB3aLS1vYdcqpJiEcyg xen/include/asm-x86/x86_64/regs.h
 40e1966azOJZfNI6Ilthe6Q-T3Hewg xen/include/asm-x86/x86_64/string.h
index efda2eac13bf73e4c0172f3aec95ebc697b378b8..3bdfd7a4b478b75bf7d883ea1611733564dd878b 100644 (file)
@@ -1599,11 +1599,7 @@ init386(void)
        gdt_segs[GDATA_SEL].ssd_limit = atop(0 - ((1 << 26) - (1 << 22) + (1 << 16))); 
 #endif
 #ifdef SMP
-       /* XXX this will blow up if there are more than 512/NGDT vcpus - will never 
-        * be an issue in the real world but should add an assert on general principles
-        * we'll likely blow up when we hit LAST_RESERVED_GDT_ENTRY, at which point we
-        * would need to start allocating more pages for the GDT
-        */
+       /* XXX this will blow up if there are more than 512/NGDT vcpus */
        pc = &SMP_prvspace[0].pcpu;
        for (i = 0; i < ncpus; i++) {
                cpu_add(i, (i == 0));
@@ -1633,7 +1629,7 @@ init386(void)
 
        PT_SET_MA(gdt, *vtopte((unsigned long)gdt) & ~PG_RW);
        gdtmachpfn = vtomach(gdt) >> PAGE_SHIFT;
-       PANIC_IF(HYPERVISOR_set_gdt(&gdtmachpfn, LAST_RESERVED_GDT_ENTRY + 1) != 0);
+       PANIC_IF(HYPERVISOR_set_gdt(&gdtmachpfn, 512) != 0);
 
        
        lgdt_finish();
index 5ef412ac212aea05e416d45efcf00663820c4bf1..d084a54303435085fd3b10d19619632035a6cfc8 100644 (file)
@@ -533,7 +533,7 @@ init_secondary(void)
        myid = bootAP;
 
        gdtmachpfn = vtomach(gdt) >> PAGE_SHIFT;
-       PANIC_IF(HYPERVISOR_set_gdt(&gdtmachpfn, LAST_RESERVED_GDT_ENTRY + 1) != 0); 
+       PANIC_IF(HYPERVISOR_set_gdt(&gdtmachpfn, 512) != 0); 
 
        
        lgdt_finish();
index 9a158e290083e3a3428162af7d222ca1e4b6bd2e..a7160953762a618153048a51b34ebbc82d7f4d27 100644 (file)
@@ -856,9 +856,6 @@ static int __init do_boot_cpu(int apicid)
        cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size;
        memcpy((void *)cpu_gdt_descr[cpu].address,
               (void *)cpu_gdt_descr[0].address, cpu_gdt_descr[0].size);
-               memset((char *)cpu_gdt_descr[cpu].address +
-                      FIRST_RESERVED_GDT_ENTRY * 8, 0,
-                      NR_RESERVED_GDT_ENTRIES * 8);
 
        memset(&ctxt, 0, sizeof(ctxt));
 
index a9657fbe740ebf45fcb579d095e977bc7e573e0a..5496d69023b1d0bd77e773bbf8a83dbddf896d7f 100644 (file)
@@ -74,9 +74,9 @@
 #define GDT_ENTRY_DOUBLEFAULT_TSS      31
 
 /*
- * The GDT has LAST_RESERVED_GDT_ENTRY + 1 entries
+ * The GDT has 32 entries
  */
-#define GDT_ENTRIES (LAST_RESERVED_GDT_ENTRY + 1)
+#define GDT_ENTRIES 32
 
 #define GDT_SIZE (GDT_ENTRIES * 8)
 
index 586469716fdadeb5312fc47b2807b1cd2e14a8ed..db5926a9999de5679088f5d4603fa4112602a542 100644 (file)
@@ -40,7 +40,7 @@
 #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3)
 
 #define IDT_ENTRIES 256
-#define GDT_ENTRIES (LAST_RESERVED_GDT_ENTRY + 1)
+#define GDT_ENTRIES 16
 #define GDT_SIZE (GDT_ENTRIES * 8)
 #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) 
 
index 54752025b672de9533d78cc769d7b72256dcdde8..54cf3fa61947442b85a5130b9b2edd80e90faf9d 100644 (file)
@@ -1430,8 +1430,8 @@ initgdt()
        pmap_kenter_pa((vaddr_t)gdt, (uint32_t)gdt - KERNBASE,
            VM_PROT_READ);
        XENPRINTK(("loading gdt %lx, %d entries\n", frames[0] << PAGE_SHIFT,
-           LAST_RESERVED_GDT_ENTRY + 1));
-       if (HYPERVISOR_set_gdt(frames, LAST_RESERVED_GDT_ENTRY + 1))
+           NGDT);
+       if (HYPERVISOR_set_gdt(frames, NGDT))
                panic("HYPERVISOR_set_gdt failed!\n");
        lgdt_finish();
 #endif
index 0d05d0f90345512570881ca95be0c0b2b7b2dd27..d50d73843962621304e9627d8a30483f692d3c71 100644 (file)
@@ -535,13 +535,6 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
         ctxt.gdt_frames[i] = pfn_to_mfn_table[pfn];
     }
 
-    /* Zero hypervisor GDT entries (supresses ugly warning) */
-    p_gdt = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_WRITE, ctxt.gdt_frames[0]);
-    memset( p_gdt + FIRST_RESERVED_GDT_ENTRY*8, 0,
-               NR_RESERVED_GDT_ENTRIES*8 );
-    munmap( p_gdt, PAGE_SIZE );
-
     /* Uncanonicalise the page table base pointer. */
     pfn = ctxt.pt_base >> PAGE_SHIFT;
     if ( (pfn >= nr_pfns) || ((pfn_type[pfn]&LTABTYPE_MASK) != L2TAB) )
index 49d6e34bb392a3d273c9d642f0a74b568bddf5a0..74edbe1ebf9a699045980ba38efa464296f97e51 100644 (file)
@@ -1,5 +1,6 @@
 #include <xen/config.h>
 #include <public/xen.h>
+#include <asm/desc.h>
 #include <asm/page.h>
 
 #define  SECONDARY_CPU_FLAG 0xA5A5A5A5
@@ -181,40 +182,39 @@ ENTRY(stack_start)
         
         .word   0    
 idt_descr:
-       .word   256*8-1
+        .word  256*8-1
 idt:
         .long  idt_table
 
         .word   0
 gdt_descr:
-       .word   (LAST_RESERVED_GDT_ENTRY*8)+7
-gdt:       
-        .long   gdt_table      /* gdt base */
+        .word  LAST_RESERVED_GDT_BYTE
+gdt:
+        .long   gdt_table - FIRST_RESERVED_GDT_BYTE
 
         .word   0
 nopaging_gdt_descr:
-        .word   (LAST_RESERVED_GDT_ENTRY*8)+7
-        .long   gdt_table-__PAGE_OFFSET
+        .word  LAST_RESERVED_GDT_BYTE
+        .long   gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET
         
-        ALIGN
+        .org 0x1000
 /* NB. Rings != 0 get access up to 0xFC400000. This allows access to the */
 /*     machine->physical mapping table. Ring 0 can access all memory.    */
 ENTRY(gdt_table)
-        .fill FIRST_RESERVED_GDT_ENTRY,8,0
         .quad 0x0000000000000000     /* unused */
-        .quad 0x00cf9a000000ffff     /* 0x0808 ring 0 4.00GB code at 0x0 */
-        .quad 0x00cf92000000ffff     /* 0x0810 ring 0 4.00GB data at 0x0 */
-        .quad 0x00cfba000000c3ff     /* 0x0819 ring 1 3.95GB code at 0x0 */
-        .quad 0x00cfb2000000c3ff     /* 0x0821 ring 1 3.95GB data at 0x0 */
-        .quad 0x00cffa000000c3ff     /* 0x082b ring 3 3.95GB code at 0x0 */
-        .quad 0x00cff2000000c3ff     /* 0x0833 ring 3 3.95GB data at 0x0 */
+        .quad 0x00cf9a000000ffff     /* 0xe008 ring 0 4.00GB code at 0x0 */
+        .quad 0x00cf92000000ffff     /* 0xe010 ring 0 4.00GB data at 0x0 */
+        .quad 0x00cfba000000c3ff     /* 0xe019 ring 1 3.95GB code at 0x0 */
+        .quad 0x00cfb2000000c3ff     /* 0xe021 ring 1 3.95GB data at 0x0 */
+        .quad 0x00cffa000000c3ff     /* 0xe02b ring 3 3.95GB code at 0x0 */
+        .quad 0x00cff2000000c3ff     /* 0xe033 ring 3 3.95GB data at 0x0 */
         .quad 0x0000000000000000     /* unused                           */
         .fill 2*NR_CPUS,8,0          /* space for TSS and LDT per CPU    */
 
-        .org 0x1000
-ENTRY(idle_pg_table) # Initial page directory is 4kB
         .org 0x2000
+ENTRY(idle_pg_table) # Initial page directory is 4kB
+        .org 0x3000
 ENTRY(cpu0_stack)
-        .org 0x2000 + STACK_SIZE
+        .org 0x3000 + STACK_SIZE
 ENTRY(stext)
 ENTRY(_stext)
index 26193cb86e7a673680c8d851be0d2e39b21f3259..56b2dcb5e56977edeeda8963dcf4d9b25cbc7f5a 100644 (file)
@@ -1,5 +1,6 @@
 #include <xen/config.h>
 #include <public/xen.h>
+#include <asm/desc.h>
 #include <asm/page.h>
 #include <asm/msr.h>
 
@@ -51,7 +52,7 @@ __start:
         cli
 
         /* Set up a few descriptors: on entry only CS is guaranteed good. */
-        lgdt    %cs:0x1001f0
+        lgdt    %cs:0x100400
         mov     $(__HYPERVISOR_DS32),%ecx
         mov     %ecx,%ds
         mov     %ecx,%es
@@ -64,7 +65,7 @@ __start:
         jne     not_multiboot
         
         /* Save the Multiboot info structure for later use. */
-        mov     %ebx,0x1001e0
+        mov     %ebx,0x100300
 
         /* We begin by interrogating the CPU for the presence of long mode. */
         mov     $0x80000000,%eax
@@ -167,44 +168,40 @@ __high_start:
         loop    1b
 
         /* Pass off the Multiboot info structure to C land. */
-        mov     0x1001e0,%edi
+        mov     0x100300,%edi
         lea     start(%rip),%rax
         sub     $0x100000,%rax
         add     %rax,%rdi
         call    __start_xen
         ud2     /* Force a panic (invalid opcode). */
 
+/* This is the default interrupt handler. */
+int_msg:
+        .asciz "Unknown interrupt\n"
+ignore_int:
+        cld
+        leaq    int_msg(%rip),%rdi
+        call    printf
+1:      jmp     1b
+
         .code32
 
-        .org    0x1e0
+        .org    0x300
                         
 /*** DESCRIPTOR TABLES ***/
 
 .globl idt
-.globl gdt        
+.globl gdt
 
-        .org    0x1f0
-        .word   (LAST_RESERVED_GDT_ENTRY*8)+7
-        .long   0x100200 # gdt_table
+        .org    0x400
+        .word   LAST_RESERVED_GDT_BYTE
+        .long   0x101000 - FIRST_RESERVED_GDT_BYTE
         
-        .org    0x200
-ENTRY(gdt_table)
-        .fill FIRST_RESERVED_GDT_ENTRY,8,0
-        .quad 0x0000000000000000     /* unused */
-        .quad 0x00cf9a000000ffff     /* 0x0808 ring 0 code, compatibility */
-        .quad 0x00af9a000000ffff     /* 0x0810 ring 0 code, 64-bit mode   */
-        .quad 0x00cf92000000ffff     /* 0x0818 ring 0 data                */
-        .quad 0x00cffa000000ffff     /* 0x0823 ring 3 code, compatibility */
-        .quad 0x00cff2000000ffff     /* 0x082b ring 3 data                */
-        .quad 0x00affa000000ffff     /* 0x0833 ring 3 code, 64-bit mode   */
-        .quad 0x0000000000000000     /* unused                            */
-        .fill 4*NR_CPUS,8,0          /* space for TSS and LDT per CPU     */
-
         .word   0
 gdt_descr:
-        .word   (LAST_RESERVED_GDT_ENTRY*8)+7
+        .word   LAST_RESERVED_GDT_BYTE
 gdt:       
-        .quad   gdt_table
+        .quad   gdt_table - FIRST_RESERVED_GDT_BYTE
 
         .word   0    
 idt_descr:
@@ -218,8 +215,20 @@ ENTRY(stack_start)
 high_start:
         .quad   __high_start
                 
+        .org    0x1000
+ENTRY(gdt_table)
+        .quad 0x0000000000000000     /* unused */
+        .quad 0x00cf9a000000ffff     /* 0xe008 ring 0 code, compatibility */
+        .quad 0x00af9a000000ffff     /* 0xe010 ring 0 code, 64-bit mode   */
+        .quad 0x00cf92000000ffff     /* 0xe018 ring 0 data                */
+        .quad 0x00cffa000000ffff     /* 0xe023 ring 3 code, compatibility */
+        .quad 0x00cff2000000ffff     /* 0xe02b ring 3 data                */
+        .quad 0x00affa000000ffff     /* 0xe033 ring 3 code, 64-bit mode   */
+        .quad 0x0000000000000000     /* unused                            */
+        .fill 4*NR_CPUS,8,0          /* space for TSS and LDT per CPU     */
+
 /* Initial PML4 -- level-4 page table */
-        .org 0x1000
+        .org 0x2000
 ENTRY(idle_pg_table)
 ENTRY(idle_pg_table_4)
         .quad 0x0000000000102007 # PML4[0]
@@ -227,12 +236,12 @@ ENTRY(idle_pg_table_4)
         .quad 0x0000000000102007 # PML4[262]
 
 /* Initial PDP -- level-3 page table */
-        .org 0x2000
+        .org 0x3000
 ENTRY(idle_pg_table_l3)
         .quad 0x0000000000103007
 
 /* Initial PDE -- level-2 page table. */
-        .org 0x3000
+        .org 0x4000
 ENTRY(idle_pg_table_l2)
         .macro identmap from=0, count=512
         .if \count-1
@@ -244,20 +253,10 @@ ENTRY(idle_pg_table_l2)
         .endm
         identmap /* Too orangey for crows :-) */
 
-        .org 0x4000
+        .org 0x5000
 ENTRY(cpu0_stack)
 
-        .org 0x4000 + STACK_SIZE
+        .org 0x5000 + STACK_SIZE
         .code64
 ENTRY(stext)
 ENTRY(_stext)
-
-/* This is the default interrupt handler. */
-int_msg:
-        .asciz "Unknown interrupt\n"
-ignore_int:
-        cld
-        leaq    int_msg(%rip),%rdi
-        call    printf
-1:      jmp     1b
-
index fb4bd53338788779f3bfc66d7844a85dcb418029..85fbe494f19b3205d9bfcfbf094b86c5beca9b04 100644 (file)
@@ -376,7 +376,6 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
 void arch_getdomaininfo_ctxt(
     struct exec_domain *ed, struct vcpu_guest_context *c)
 { 
-    int i;
 #ifdef __i386__  /* Remove when x86_64 VMX is implemented */
 #ifdef CONFIG_VMX
     extern void save_vmx_cpu_user_regs(struct cpu_user_regs *);
@@ -406,15 +405,6 @@ void arch_getdomaininfo_ctxt(
         c->flags |= VGCF_VMX_GUEST;
 #endif
 
-    c->gdt_ents = 0;
-    if ( GET_GDT_ADDRESS(ed) == GDT_VIRT_START(ed) )
-    {
-        for ( i = 0; i < 16; i++ )
-            c->gdt_frames[i] = 
-                l1e_get_pfn(ed->arch.perdomain_ptes[i]);
-        c->gdt_ents = GET_GDT_ENTRIES(ed);
-    }
-
     c->pt_base = pagetable_val(ed->arch.guest_table);
 
     c->vm_assist = ed->domain->vm_assist;
index e99f4f4743d6779618588ad5eaeb3b482f53054b..0b93ed87a269ff249e3d45b703122334307e4b4e 100644 (file)
@@ -244,57 +244,66 @@ void arch_do_createdomain(struct exec_domain *ed)
 
     ed->arch.flags = TF_kernel_mode;
 
-    if ( d->domain_id != IDLE_DOMAIN_ID )
-    {
-        ed->arch.schedule_tail = continue_nonidle_task;
-
-        d->shared_info = (void *)alloc_xenheap_page();
-        memset(d->shared_info, 0, PAGE_SIZE);
-        ed->vcpu_info = &d->shared_info->vcpu_data[ed->vcpu_id];
-        ed->cpumap = CPUMAP_RUNANYWHERE;
-        SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
-        machine_to_phys_mapping[virt_to_phys(d->shared_info) >> 
-                               PAGE_SHIFT] = INVALID_M2P_ENTRY;
-
-        d->arch.mm_perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page();
-        memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE);
-        machine_to_phys_mapping[virt_to_phys(d->arch.mm_perdomain_pt) >> 
-                               PAGE_SHIFT] = INVALID_M2P_ENTRY;
-        ed->arch.perdomain_ptes = d->arch.mm_perdomain_pt;
+    if ( d->domain_id == IDLE_DOMAIN_ID )
+        return;
 
-        ed->arch.guest_vtable  = __linear_l2_table;
-        ed->arch.shadow_vtable = __shadow_linear_l2_table;
+    ed->arch.schedule_tail = continue_nonidle_task;
+    
+    d->shared_info = (void *)alloc_xenheap_page();
+    memset(d->shared_info, 0, PAGE_SIZE);
+    ed->vcpu_info = &d->shared_info->vcpu_data[ed->vcpu_id];
+    ed->cpumap = CPUMAP_RUNANYWHERE;
+    SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
+    machine_to_phys_mapping[virt_to_phys(d->shared_info) >> 
+                           PAGE_SHIFT] = INVALID_M2P_ENTRY;
+    
+    d->arch.mm_perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page();
+    memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE);
+    machine_to_phys_mapping[virt_to_phys(d->arch.mm_perdomain_pt) >> 
+                           PAGE_SHIFT] = INVALID_M2P_ENTRY;
+    ed->arch.perdomain_ptes = d->arch.mm_perdomain_pt;
+    ed->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] =
+        l1e_create_pfn(page_to_pfn(virt_to_page(gdt_table)),
+                       __PAGE_HYPERVISOR);
+    
+    ed->arch.guest_vtable  = __linear_l2_table;
+    ed->arch.shadow_vtable = __shadow_linear_l2_table;
 
 #ifdef __x86_64__
-        ed->arch.guest_vl3table = __linear_l3_table;
-        ed->arch.guest_vl4table = __linear_l4_table;
-
-        d->arch.mm_perdomain_l2 = (l2_pgentry_t *)alloc_xenheap_page();
-        memset(d->arch.mm_perdomain_l2, 0, PAGE_SIZE);
-        d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)] = 
-            l2e_create_phys(__pa(d->arch.mm_perdomain_pt),
-                            __PAGE_HYPERVISOR);
-        d->arch.mm_perdomain_l3 = (l3_pgentry_t *)alloc_xenheap_page();
-        memset(d->arch.mm_perdomain_l3, 0, PAGE_SIZE);
-        d->arch.mm_perdomain_l3[l3_table_offset(PERDOMAIN_VIRT_START)] = 
-            l3e_create_phys(__pa(d->arch.mm_perdomain_l2),
+    ed->arch.guest_vl3table = __linear_l3_table;
+    ed->arch.guest_vl4table = __linear_l4_table;
+    
+    d->arch.mm_perdomain_l2 = (l2_pgentry_t *)alloc_xenheap_page();
+    memset(d->arch.mm_perdomain_l2, 0, PAGE_SIZE);
+    d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)] = 
+        l2e_create_phys(__pa(d->arch.mm_perdomain_pt),
+                        __PAGE_HYPERVISOR);
+    d->arch.mm_perdomain_l3 = (l3_pgentry_t *)alloc_xenheap_page();
+    memset(d->arch.mm_perdomain_l3, 0, PAGE_SIZE);
+    d->arch.mm_perdomain_l3[l3_table_offset(PERDOMAIN_VIRT_START)] = 
+        l3e_create_phys(__pa(d->arch.mm_perdomain_l2),
                             __PAGE_HYPERVISOR);
 #endif
-
-        (void)ptwr_init(d);
-
-        shadow_lock_init(d);        
-        INIT_LIST_HEAD(&d->arch.free_shadow_frames);
-    }
+    
+    (void)ptwr_init(d);
+    
+    shadow_lock_init(d);        
+    INIT_LIST_HEAD(&d->arch.free_shadow_frames);
 }
 
 void arch_do_boot_vcpu(struct exec_domain *ed)
 {
     struct domain *d = ed->domain;
+
+    ed->arch.flags = TF_kernel_mode;
+
     ed->arch.schedule_tail = d->exec_domain[0]->arch.schedule_tail;
-    ed->arch.perdomain_ptes = 
+
+    ed->arch.perdomain_ptes =
         d->arch.mm_perdomain_pt + (ed->vcpu_id << PDPT_VCPU_SHIFT);
-    ed->arch.flags = TF_kernel_mode;
+    ed->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] =
+        l1e_create_pfn(page_to_pfn(virt_to_page(gdt_table)),
+                       __PAGE_HYPERVISOR);
 }
 
 #ifdef CONFIG_VMX
@@ -444,16 +453,10 @@ int arch_set_info_guest(
             return -EINVAL;
     }
 
-    /* Failure to set GDT is harmless. */
-    SET_GDT_ENTRIES(ed, DEFAULT_GDT_ENTRIES);
-    SET_GDT_ADDRESS(ed, DEFAULT_GDT_ADDRESS);
-    if ( c->gdt_ents != 0 )
+    if ( (rc = (int)set_gdt(ed, c->gdt_frames, c->gdt_ents)) != 0 )
     {
-        if ( (rc = (int)set_gdt(ed, c->gdt_frames, c->gdt_ents)) != 0 )
-        {
-            put_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT]);
-            return rc;
-        }
+        put_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT]);
+        return rc;
     }
 
 #ifdef CONFIG_VMX
@@ -754,7 +757,14 @@ static void __context_switch(void)
         set_bit(cpu, &n->domain->cpuset);
 
     write_ptbase(n);
-    __asm__ __volatile__ ( "lgdt %0" : "=m" (*n->arch.gdt) );
+
+    if ( p->vcpu_id != n->vcpu_id )
+    {
+        char gdt_load[10];
+        *(unsigned short *)(&gdt_load[0]) = LAST_RESERVED_GDT_BYTE;
+        *(unsigned long  *)(&gdt_load[2]) = GDT_VIRT_START(n);
+        __asm__ __volatile__ ( "lgdt %0" : "=m" (gdt_load) );
+    }
 
     if ( p->domain != n->domain )
         clear_bit(cpu, &p->domain->cpuset);
index 560cea0a99099fa9a385b88a1a9262fdd3d8a15c..72ded37bdc46ba28d704658d4b749c0aadf7f086 100644 (file)
@@ -225,9 +225,6 @@ int construct_dom0(struct domain *d,
 
     mpt_alloc = (vpt_start - dsi.v_start) + alloc_start;
 
-    SET_GDT_ENTRIES(ed, DEFAULT_GDT_ENTRIES);
-    SET_GDT_ADDRESS(ed, DEFAULT_GDT_ADDRESS);
-
     /*
      * We're basically forcing default RPLs to 1, so that our "what privilege
      * level are we returning to?" logic works.
index afbdeaa81da40ba9850fbdbdca5cc8eea90f5c26..ccf8e3725a59db875aad8f001dba78533664e696 100644 (file)
@@ -2244,11 +2244,13 @@ void destroy_gdt(struct exec_domain *ed)
     int i;
     unsigned long pfn;
 
-    for ( i = 0; i < 16; i++ )
+    ed->arch.guest_context.gdt_ents = 0;
+    for ( i = 0; i < FIRST_RESERVED_GDT_PAGE; i++ )
     {
         if ( (pfn = l1e_get_pfn(ed->arch.perdomain_ptes[i])) != 0 )
             put_page_and_type(&frame_table[pfn]);
         ed->arch.perdomain_ptes[i] = l1e_empty();
+        ed->arch.guest_context.gdt_frames[i] = 0;
     }
 }
 
@@ -2259,56 +2261,31 @@ long set_gdt(struct exec_domain *ed,
 {
     struct domain *d = ed->domain;
     /* NB. There are 512 8-byte entries per GDT page. */
-    int i = 0, nr_pages = (entries + 511) / 512;
-    struct desc_struct *vgdt;
+    int i, nr_pages = (entries + 511) / 512;
     unsigned long pfn;
 
-    /* Check the first page in the new GDT. */
-    if ( (pfn = frames[0]) >= max_page )
-        goto fail;
-
+    if ( entries > FIRST_RESERVED_GDT_ENTRY )
+        return -EINVAL;
+    
     shadow_sync_all(d);
 
-    /* The first page is special because Xen owns a range of entries in it. */
-    if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
-    {
-        /* GDT checks failed: try zapping the Xen reserved entries. */
-        if ( !get_page_and_type(&frame_table[pfn], d, PGT_writable_page) )
-            goto fail;
-        vgdt = map_domain_mem(pfn << PAGE_SHIFT);
-        memset(vgdt + FIRST_RESERVED_GDT_ENTRY, 0,
-               NR_RESERVED_GDT_ENTRIES*8);
-        unmap_domain_mem(vgdt);
-        put_page_and_type(&frame_table[pfn]);
-
-        /* Okay, we zapped the entries. Now try the GDT checks again. */
-        if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
-            goto fail;
-    }
-
-    /* Check the remaining pages in the new GDT. */
-    for ( i = 1; i < nr_pages; i++ )
+    /* Check the pages in the new GDT. */
+    for ( i = 0; i < nr_pages; i++ )
         if ( ((pfn = frames[i]) >= max_page) ||
              !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
             goto fail;
 
-    /* Copy reserved GDT entries to the new GDT. */
-    vgdt = map_domain_mem(frames[0] << PAGE_SHIFT);
-    memcpy(vgdt + FIRST_RESERVED_GDT_ENTRY, 
-           gdt_table + FIRST_RESERVED_GDT_ENTRY, 
-           NR_RESERVED_GDT_ENTRIES*8);
-    unmap_domain_mem(vgdt);
-
     /* Tear down the old GDT. */
     destroy_gdt(ed);
 
     /* Install the new GDT. */
+    ed->arch.guest_context.gdt_ents = entries;
     for ( i = 0; i < nr_pages; i++ )
+    {
+        ed->arch.guest_context.gdt_frames[i] = frames[i];
         ed->arch.perdomain_ptes[i] =
             l1e_create_pfn(frames[i], __PAGE_HYPERVISOR);
-
-    SET_GDT_ADDRESS(ed, GDT_VIRT_START(ed));
-    SET_GDT_ENTRIES(ed, entries);
+    }
 
     return 0;
 
@@ -2325,19 +2302,13 @@ long do_set_gdt(unsigned long *frame_list, unsigned int entries)
     unsigned long frames[16];
     long ret;
 
-    if ( (entries <= LAST_RESERVED_GDT_ENTRY) || (entries > 8192) ) 
-        return -EINVAL;
-    
     if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) )
         return -EFAULT;
 
     LOCK_BIGLOCK(current->domain);
 
     if ( (ret = set_gdt(current, frames, entries)) == 0 )
-    {
         local_flush_tlb();
-        __asm__ __volatile__ ("lgdt %0" : "=m" (*current->arch.gdt));
-    }
 
     UNLOCK_BIGLOCK(current->domain);
 
@@ -2352,7 +2323,6 @@ long do_update_descriptor(unsigned long pa, u64 desc)
     unsigned long mfn;
     struct desc_struct *gdt_pent, d;
     struct pfn_info *page;
-    struct exec_domain *ed;
     long ret = -EINVAL;
 
     *(u64 *)&d = desc;
@@ -2379,13 +2349,6 @@ long do_update_descriptor(unsigned long pa, u64 desc)
     switch ( page->u.inuse.type_info & PGT_type_mask )
     {
     case PGT_gdt_page:
-        /* Disallow updates of Xen-reserved descriptors in the current GDT. */
-        for_each_exec_domain(dom, ed) {
-            if ( (l1e_get_pfn(ed->arch.perdomain_ptes[0]) == mfn) &&
-                 (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) &&
-                 (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) )
-                goto out;
-        }
         if ( unlikely(!get_page_type(page, PGT_gdt_page)) )
             goto out;
         break;
index 49eb0d275bd0e6a81524989b3a0d7cf786d57ffc..05721b5d2c0c15182ddd5982638466552efdc765 100644 (file)
@@ -295,14 +295,15 @@ void __init cpu_init(void)
 {
     int nr = smp_processor_id();
     struct tss_struct *t = &init_tss[nr];
+    char gdt_load[10];
 
     if ( test_and_set_bit(nr, &cpu_initialized) )
         panic("CPU#%d already initialized!!!\n", nr);
     printk("Initializing CPU#%d\n", nr);
 
-    SET_GDT_ENTRIES(current, DEFAULT_GDT_ENTRIES);
-    SET_GDT_ADDRESS(current, DEFAULT_GDT_ADDRESS);
-    __asm__ __volatile__ ( "lgdt %0" : "=m" (*current->arch.gdt) );
+    *(unsigned short *)(&gdt_load[0]) = LAST_RESERVED_GDT_BYTE;
+    *(unsigned long  *)(&gdt_load[2]) = GDT_VIRT_START(current);
+    __asm__ __volatile__ ( "lgdt %0" : "=m" (gdt_load) );
 
     /* No nested task. */
     __asm__ __volatile__ ( "pushf ; andw $0xbfff,(%"__OP"sp) ; popf" );
@@ -391,10 +392,19 @@ static void __init start_of_day(void)
     sort_exception_tables();
 
     arch_do_createdomain(current);
-
-    identify_cpu(&boot_cpu_data); /* get CPU type info */
-    if ( cpu_has_fxsr ) set_in_cr4(X86_CR4_OSFXSR);
-    if ( cpu_has_xmm )  set_in_cr4(X86_CR4_OSXMMEXCPT);
+    
+    /* Map default GDT into their final position in the idle page table. */
+    map_pages(
+        idle_pg_table,
+        GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE,
+        virt_to_phys(gdt_table), PAGE_SIZE, __PAGE_HYPERVISOR);
+
+    /* Process CPU type information. */
+    identify_cpu(&boot_cpu_data);
+    if ( cpu_has_fxsr )
+        set_in_cr4(X86_CR4_OSFXSR);
+    if ( cpu_has_xmm )
+        set_in_cr4(X86_CR4_OSXMMEXCPT);
 
     find_smp_config();
 
index f72afac0ce828b88f174e256818e829458b8c04b..44baea0bbbd4b6b1cba689c8e77d4f2aed0965be 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <xen/config.h>
 #include <public/xen.h>
+#include <asm/desc.h>
 #include <asm/page.h>
 
 #ifdef CONFIG_SMP
@@ -54,11 +55,11 @@ idt_48:
        .word   0, 0                    # idt base = 0L
 
 gdt_48:
-       .word   (LAST_RESERVED_GDT_ENTRY*8)+7
+       .word   LAST_RESERVED_GDT_BYTE
 #ifdef __i386__
-       .long   gdt_table-__PAGE_OFFSET
+       .long   gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET
 #else
-       .long   0x100200 # gdt_table
+       .long   0x101000 - FIRST_RESERVED_GDT_BYTE
 #endif
 
 ENTRY(trampoline_end)
index 8851e30b87b7f8497917323d5c81fca96cfdd396..da39f5c9660a25aef61900324cf2887c72c77390 100644 (file)
@@ -70,25 +70,29 @@ string_param("nmi", opt_nmi);
 /* Master table, used by all CPUs on x86/64, and by CPU0 on x86/32.*/
 idt_entry_t idt_table[IDT_ENTRIES];
 
-asmlinkage void divide_error(void);
-asmlinkage void debug(void);
+#define DECLARE_TRAP_HANDLER(_name)                     \
+asmlinkage void _name(void);                            \
+asmlinkage int do_ ## _name(struct cpu_user_regs *regs)
+
 asmlinkage void nmi(void);
-asmlinkage void int3(void);
-asmlinkage void overflow(void);
-asmlinkage void bounds(void);
-asmlinkage void invalid_op(void);
-asmlinkage void device_not_available(void);
-asmlinkage void coprocessor_segment_overrun(void);
-asmlinkage void invalid_TSS(void);
-asmlinkage void segment_not_present(void);
-asmlinkage void stack_segment(void);
-asmlinkage void general_protection(void);
-asmlinkage void page_fault(void);
-asmlinkage void coprocessor_error(void);
-asmlinkage void simd_coprocessor_error(void);
-asmlinkage void alignment_check(void);
-asmlinkage void spurious_interrupt_bug(void);
-asmlinkage void machine_check(void);
+DECLARE_TRAP_HANDLER(divide_error);
+DECLARE_TRAP_HANDLER(debug);
+DECLARE_TRAP_HANDLER(int3);
+DECLARE_TRAP_HANDLER(overflow);
+DECLARE_TRAP_HANDLER(bounds);
+DECLARE_TRAP_HANDLER(invalid_op);
+DECLARE_TRAP_HANDLER(device_not_available);
+DECLARE_TRAP_HANDLER(coprocessor_segment_overrun);
+DECLARE_TRAP_HANDLER(invalid_TSS);
+DECLARE_TRAP_HANDLER(segment_not_present);
+DECLARE_TRAP_HANDLER(stack_segment);
+DECLARE_TRAP_HANDLER(general_protection);
+DECLARE_TRAP_HANDLER(page_fault);
+DECLARE_TRAP_HANDLER(coprocessor_error);
+DECLARE_TRAP_HANDLER(simd_coprocessor_error);
+DECLARE_TRAP_HANDLER(alignment_check);
+DECLARE_TRAP_HANDLER(spurious_interrupt_bug);
+DECLARE_TRAP_HANDLER(machine_check);
 
 static int debug_stack_lines = 20;
 integer_param("debug_stack_lines", debug_stack_lines);
@@ -327,9 +331,10 @@ asmlinkage int do_int3(struct cpu_user_regs *regs)
     return 0;
 }
 
-asmlinkage void do_machine_check(struct cpu_user_regs *regs)
+asmlinkage int do_machine_check(struct cpu_user_regs *regs)
 {
     fatal_trap(TRAP_machine_check, regs);
+    return 0;
 }
 
 void propagate_page_fault(unsigned long addr, u16 error_code)
@@ -350,12 +355,57 @@ void propagate_page_fault(unsigned long addr, u16 error_code)
     ed->arch.guest_cr2 = addr;
 }
 
+static int handle_perdomain_mapping_fault(
+    unsigned long offset, struct cpu_user_regs *regs)
+{
+    extern int map_ldt_shadow_page(unsigned int);
+
+    struct exec_domain *ed = current;
+    struct domain      *d  = ed->domain;
+    int ret;
+
+    /* Which vcpu's area did we fault in, and is it in the ldt sub-area? */
+    unsigned int is_ldt_area = (offset >> (PDPT_VCPU_VA_SHIFT-1)) & 1;
+    unsigned int vcpu_area   = (offset >> PDPT_VCPU_VA_SHIFT);
+
+    /* Should never fault in another vcpu's area. */
+    BUG_ON(vcpu_area != current->vcpu_id);
+
+    /* Byte offset within the gdt/ldt sub-area. */
+    offset &= (1UL << (PDPT_VCPU_VA_SHIFT-1)) - 1UL;
+
+    if ( likely(is_ldt_area) )
+    {
+        /* LDT fault: Copy a mapping from the guest's LDT, if it is valid. */
+        LOCK_BIGLOCK(d);
+        ret = map_ldt_shadow_page(offset >> PAGE_SHIFT);
+        UNLOCK_BIGLOCK(d);
+
+        if ( unlikely(ret == 0) )
+        {
+            /* In hypervisor mode? Leave it to the #PF handler to fix up. */
+            if ( !GUEST_MODE(regs) )
+                return 0;
+            /* In guest mode? Propagate #PF to guest, with adjusted %cr2. */
+            propagate_page_fault(
+                ed->arch.guest_context.ldt_base + offset, regs->error_code);
+        }
+    }
+    else
+    {
+        /* GDT fault: handle the fault as #GP(selector). */
+        regs->error_code = (u16)offset & ~7;
+        (void)do_general_protection(regs);
+    }
+
+    return EXCRET_fault_fixed;
+}
+
 asmlinkage int do_page_fault(struct cpu_user_regs *regs)
 {
-    unsigned long off, addr, fixup;
+    unsigned long addr, fixup;
     struct exec_domain *ed = current;
     struct domain *d = ed->domain;
-    int ret;
 
     __asm__ __volatile__ ("mov %%cr2,%0" : "=r" (addr) : );
 
@@ -390,27 +440,12 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs)
          ((addr < HYPERVISOR_VIRT_START) ||
           (shadow_mode_external(d) && GUEST_CONTEXT(ed, regs))) &&
          shadow_fault(addr, regs) )
-    {
         return EXCRET_fault_fixed;
-    }
 
-    if ( unlikely(addr >= LDT_VIRT_START(ed)) && 
-         (addr < (LDT_VIRT_START(ed) + 
-                  (ed->arch.guest_context.ldt_ents*LDT_ENTRY_SIZE))) )
-    {
-        /*
-         * Copy a mapping from the guest's LDT, if it is valid. Otherwise we
-         * send the fault up to the guest OS to be handled.
-         */
-        extern int map_ldt_shadow_page(unsigned int);
-        LOCK_BIGLOCK(d);
-        off  = addr - LDT_VIRT_START(ed);
-        addr = ed->arch.guest_context.ldt_base + off;
-        ret = map_ldt_shadow_page(off >> PAGE_SHIFT);
-        UNLOCK_BIGLOCK(d);
-        if ( likely(ret) )
-            return EXCRET_fault_fixed; /* successfully copied the mapping */
-    }
+    if ( unlikely(addr >= PERDOMAIN_VIRT_START) &&
+         unlikely(addr < PERDOMAIN_VIRT_END) &&
+         handle_perdomain_mapping_fault(addr - PERDOMAIN_VIRT_START, regs) )
+        return EXCRET_fault_fixed;
 
     if ( !GUEST_MODE(regs) )
         goto xen_fault;
@@ -1097,7 +1132,7 @@ void set_task_gate(unsigned int n, unsigned int sel)
 void set_tss_desc(unsigned int n, void *addr)
 {
     _set_tssldt_desc(
-        gdt_table + __TSS(n),
+        gdt_table + __TSS(n) - FIRST_RESERVED_GDT_ENTRY,
         (unsigned long)addr,
         offsetof(struct tss_struct, __cacheline_filler) - 1,
         9);
index 484ff64fd468a6ff893a6ff476e8760484b59098..f0d7f8543e1ef3579c08d3d29196721735789d7c 100644 (file)
@@ -120,8 +120,8 @@ int get_baselimit(u16 seg, unsigned long *base, unsigned long *limit)
     }
     else /* gdt */
     {
-        table = (unsigned long *)GET_GDT_ADDRESS(d);
-        if ( idx >= GET_GDT_ENTRIES(d) )
+        table = (unsigned long *)GDT_VIRT_START(d);
+        if ( idx >= d->arch.guest_context.gdt_ents )
             goto fail;
     }
 
@@ -184,17 +184,17 @@ int fixup_seg(u16 seg, unsigned long offset)
         if ( idx >= d->arch.guest_context.ldt_ents )
         {
             DPRINTK("Segment %04x out of LDT range (%ld)\n",
-                    seg, d->arch.ldt_ents);
+                    seg, d->arch.guest_context.ldt_ents);
             goto fail;
         }
     }
     else /* gdt */
     {
-        table = (unsigned long *)GET_GDT_ADDRESS(d);
-        if ( idx >= GET_GDT_ENTRIES(d) )
+        table = (unsigned long *)GDT_VIRT_START(d);
+        if ( idx >= d->arch.guest_context.gdt_ents )
         {
-            DPRINTK("Segment %04x out of GDT range (%d)\n",
-                    seg, GET_GDT_ENTRIES(d));
+            DPRINTK("Segment %04x out of GDT range (%ld)\n",
+                    seg, d->arch.guest_context.gdt_ents);
             goto fail;
         }
     }
index a75badbad75a36ce07840272281f39e5fc52d51c..0e391a4ea6748067a579d5d517bc73570f0d02bd 100644 (file)
@@ -178,8 +178,9 @@ void __init percpu_traps_init(void)
     tss->eip    = (unsigned long)do_double_fault;
     tss->eflags = 2;
     tss->bitmap = IOBMP_INVALID_OFFSET;
-    _set_tssldt_desc(gdt_table+__DOUBLEFAULT_TSS_ENTRY,
-                     (unsigned long)tss, 235, 9);
+    _set_tssldt_desc(
+        gdt_table + __DOUBLEFAULT_TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
+        (unsigned long)tss, 235, 9);
 
     set_task_gate(TRAP_double_fault, __DOUBLEFAULT_TSS_ENTRY<<3);
 }
index d98a57e5a26c53fda8de085ca8df8860c7610535..5e4f6196ec6af5ee17286919259a0937f7c21752 100644 (file)
 
 #define OPT_CONSOLE_STR "com1,vga"
 
-/*
- * If you increase this value, please update NR_RESERVED_GDT_ENTRIES
- * in include/public/arch-x86_xx.h
- */
 #define NR_CPUS 32
 
 /* Linkage for x86 */
@@ -160,18 +156,18 @@ extern unsigned long _end; /* standard ELF symbol */
 
 #define PGT_base_page_table PGT_l4_page_table
 
-#define __HYPERVISOR_CS64 0x0810
-#define __HYPERVISOR_CS32 0x0808
+#define __HYPERVISOR_CS64 0xe010
+#define __HYPERVISOR_CS32 0xe008
 #define __HYPERVISOR_CS   __HYPERVISOR_CS64
 #define __HYPERVISOR_DS64 0x0000
-#define __HYPERVISOR_DS32 0x0818
+#define __HYPERVISOR_DS32 0xe018
 #define __HYPERVISOR_DS   __HYPERVISOR_DS64
 
-#define __GUEST_CS64      0x0833
-#define __GUEST_CS32      0x0823
+#define __GUEST_CS64      0xe033
+#define __GUEST_CS32      0xe023
 #define __GUEST_CS        __GUEST_CS64
 #define __GUEST_DS        0x0000
-#define __GUEST_SS        0x082b
+#define __GUEST_SS        0xe02b
 
 /* For generic assembly code: use macros to define operation/operand sizes. */
 #define __OS          "q"  /* Operation Suffix */
@@ -260,8 +256,8 @@ extern unsigned long _end; /* standard ELF symbol */
 
 #define PGT_base_page_table PGT_l2_page_table
 
-#define __HYPERVISOR_CS 0x0808
-#define __HYPERVISOR_DS 0x0810
+#define __HYPERVISOR_CS 0xe008
+#define __HYPERVISOR_DS 0xe010
 
 /* For generic assembly code: use macros to define operation/operand sizes. */
 #define __OS          "l"  /* Operation Suffix */
@@ -275,10 +271,10 @@ extern unsigned long _end; /* standard ELF symbol */
 extern unsigned long xenheap_phys_end; /* user-configurable */
 #endif
 
-#define GDT_VIRT_START(ed)    (PERDOMAIN_VIRT_START + ((ed)->vcpu_id << PDPT_VCPU_VA_SHIFT))
-#define GDT_VIRT_END(ed)      (GDT_VIRT_START(ed) + (64*1024))
-#define LDT_VIRT_START(ed)    (PERDOMAIN_VIRT_START + (64*1024) + ((ed)->vcpu_id << PDPT_VCPU_VA_SHIFT))
-#define LDT_VIRT_END(ed)      (LDT_VIRT_START(ed) + (64*1024))
+#define GDT_VIRT_START(ed)    \
+    (PERDOMAIN_VIRT_START + ((ed)->vcpu_id << PDPT_VCPU_VA_SHIFT))
+#define LDT_VIRT_START(ed)    \
+    (GDT_VIRT_START(ed) + (64*1024))
 
 #define PDPT_VCPU_SHIFT       5
 #define PDPT_VCPU_VA_SHIFT    (PDPT_VCPU_SHIFT + PAGE_SHIFT)
index a05bb752e9f48ab5b6dbeb930e43f7aab7ab07b9..6d45d0cb2b37829523f704bcc180961e6602e13d 100644 (file)
@@ -1,6 +1,20 @@
 #ifndef __ARCH_DESC_H
 #define __ARCH_DESC_H
-#ifndef __ASSEMBLY__
+
+/*
+ * Xen reserves a memory page of GDT entries.
+ * No guest GDT entries exist beyond the Xen reserved area.
+ */
+#define NR_RESERVED_GDT_PAGES   1
+#define NR_RESERVED_GDT_BYTES   (NR_RESERVED_GDT_PAGES * PAGE_SIZE)
+#define NR_RESERVED_GDT_ENTRIES (NR_RESERVED_GDT_BYTES / 8)
+
+#define LAST_RESERVED_GDT_PAGE  \
+    (FIRST_RESERVED_GDT_PAGE + NR_RESERVED_GDT_PAGES - 1)
+#define LAST_RESERVED_GDT_BYTE  \
+    (FIRST_RESERVED_GDT_BYTE + NR_RESERVED_GDT_BYTES - 1)
+#define LAST_RESERVED_GDT_ENTRY \
+    (FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1)
 
 #define LDT_ENTRY_SIZE 8
 
@@ -19,9 +33,7 @@
  * is ignored when the gate is accessed.
  */
 #define VALID_SEL(_s)                                                      \
-    (((((_s)>>3) < FIRST_RESERVED_GDT_ENTRY) ||                            \
-      (((_s)>>3) >  LAST_RESERVED_GDT_ENTRY) ||                            \
-      ((_s)&4)) &&                                                         \
+    (((((_s)>>3) < FIRST_RESERVED_GDT_ENTRY) || ((_s)&4)) &&               \
      (((_s)&3) == GUEST_KERNEL_RPL))
 #define VALID_CODESEL(_s) ((_s) == FLAT_KERNEL_CS || VALID_SEL(_s))
 
@@ -36,6 +48,8 @@
 #define _SEGMENT_DB      ( 1<<22) /* 16- or 32-bit segment */
 #define _SEGMENT_G       ( 1<<23) /* Granularity */
 
+#ifndef __ASSEMBLY__
+
 struct desc_struct {
     u32 a, b;
 };
@@ -133,4 +147,5 @@ extern void set_task_gate(unsigned int n, unsigned int sel);
 extern void set_tss_desc(unsigned int n, void *addr);
 
 #endif /* !__ASSEMBLY__ */
+
 #endif /* __ARCH_DESC_H */
index 79eda33a07452eadc0b2f864efc61123d3d635a6..98da7e017a50c065425a48fae8a95ce23c3317c4 100644 (file)
@@ -117,8 +117,6 @@ struct arch_exec_domain
 
     /* Current LDT details. */
     unsigned long shadow_ldt_mapcnt;
-    /* Next entry is passed to LGDT on domain switch. */
-    char gdt[10]; /* NB. 10 bytes needed for x86_64. Use 6 bytes for x86_32. */
 } __cacheline_aligned;
 
 #define IDLE0_ARCH_EXEC_DOMAIN                                      \
index 63fa8db5d847a88d286fdac09f2135bdec95a5e7..33de17516517f27cd31ac52f0017fe6fc1b0acdc 100644 (file)
@@ -17,7 +17,7 @@ static inline void load_LDT(struct exec_domain *ed)
     else
     {
         cpu = smp_processor_id();
-        desc = (struct desc_struct *)GET_GDT_ADDRESS(ed) + __LDT(cpu);
+        desc = gdt_table + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY;
         desc->a = ((LDT_VIRT_START(ed)&0xffff)<<16) | (ents*8-1);
         desc->b = (LDT_VIRT_START(ed)&(0xff<<24)) | 0x8200 |
             ((LDT_VIRT_START(ed)&0xff0000)>>16);
index cf4e88bc6d8d45177782ae786203fa2ebec6a432..bbab724e48de956b49155d7b0c1e43414aed065b 100644 (file)
@@ -274,9 +274,6 @@ static inline unsigned long phys_to_machine_mapping(unsigned long pfn)
 }
 #define set_machinetophys(_mfn, _pfn) machine_to_phys_mapping[(_mfn)] = (_pfn)
 
-#define DEFAULT_GDT_ENTRIES     (LAST_RESERVED_GDT_ENTRY+1)
-#define DEFAULT_GDT_ADDRESS     ((unsigned long)gdt_table)
-
 #ifdef MEMORY_GUARD
 void *memguard_init(void *heap_start);
 void memguard_guard_stack(void *p);
index 9ccfcf3f3ae4d1c2cf30e20db4807a7fe38e112c..907c820c12d7c2172d360842a14b18beefdc0b07 100644 (file)
@@ -392,15 +392,6 @@ extern int gpf_emulate_4gb(struct cpu_user_regs *regs);
 
 extern void write_ptbase(struct exec_domain *ed);
 
-#define SET_GDT_ENTRIES(_p, _e) \
-    ((*(u16 *)((_p)->arch.gdt + 0)) = (((_e)<<3)-1))
-#define SET_GDT_ADDRESS(_p, _a) \
-    ((*(unsigned long *)((_p)->arch.gdt + 2)) = (_a))
-#define GET_GDT_ENTRIES(_p)     \
-    (((*(u16 *)((_p)->arch.gdt + 0))+1)>>3)
-#define GET_GDT_ADDRESS(_p)     \
-    (*(unsigned long *)((_p)->arch.gdt + 2))
-
 void destroy_gdt(struct exec_domain *d);
 long set_gdt(struct exec_domain *d, 
              unsigned long *frames, 
diff --git a/xen/include/asm-x86/x86_64/ldt.h b/xen/include/asm-x86/x86_64/ldt.h
deleted file mode 100644 (file)
index 1e09163..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef __ARCH_LDT_H
-#define __ARCH_LDT_H
-
-#ifndef __ASSEMBLY__
-
-static inline void load_LDT(struct domain *p)
-{
-    unsigned long ents;
-
-    if ( (ents = p->mm.ldt_ents) == 0 )
-    {
-        __asm__ __volatile__ ( "lldt %w0" : : "r" (0) );
-    }
-    else
-    {
-       unsigned int cpu;
-       struct ldttss_desc *desc;
-
-        cpu = smp_processor_id();
-        desc = (struct ldttss_desc *)((char *)GET_GDT_ADDRESS(p) + __CPU_DESC_INDEX(cpu, ldt));
-       desc->limit0 = ents*8-1;
-       desc->base0 = LDT_VIRT_START&0xffff;
-       desc->base1 = (LDT_VIRT_START&0xff0000)>>16;
-       desc->type = DESC_LDT;
-       desc->dpl = 0;
-       desc->p = 1;
-       desc->limit1 = 0;
-       desc->zero0 = 0;
-       desc->g = 0;
-       desc->base2 = (LDT_VIRT_START&0xff000000)>>24;
-       desc->base3 = LDT_VIRT_START>>32;
-       desc->zero1 = 0;
-       __load_LDT(cpu);
-    }
-}
-
-#endif /* !__ASSEMBLY__ */
-
-#endif
index 35d97e2b3de95d63f2a52ba1b289ab22f416ea39..6ebfd11399e273982e8183b514d8f4def208c994 100644 (file)
  * A number of GDT entries are reserved by Xen. These are not situated at the
  * start of the GDT because some stupid OSes export hard-coded selector values
  * in their ABI. These hard-coded values are always near the start of the GDT,
- * so Xen places itself out of the way.
- * 
- * NR_RESERVED_GDT_ENTRIES is (8 + 2 * NR_CPUS) Please update this value if 
- * you increase NR_CPUS or add another GDT entry to gdt_table in x86_32.S
- *
- * NB. The reserved range is inclusive (that is, both FIRST_RESERVED_GDT_ENTRY
- * and LAST_RESERVED_GDT_ENTRY are reserved).
+ * so Xen places itself out of the way, at the far end of the GDT.
  */
-#define NR_RESERVED_GDT_ENTRIES    72
-#define FIRST_RESERVED_GDT_ENTRY   256
-#define LAST_RESERVED_GDT_ENTRY    \
-  (FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1)
-
+#define FIRST_RESERVED_GDT_PAGE  14
+#define FIRST_RESERVED_GDT_BYTE  (FIRST_RESERVED_GDT_PAGE * 4096)
+#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8)
 
 /*
  * These flat segments are in the Xen-private section of every GDT. Since these
  * are also present in the initial GDT, many OSes will be able to avoid
  * installing their own GDT.
  */
-#define FLAT_RING1_CS 0x0819    /* GDT index 259 */
-#define FLAT_RING1_DS 0x0821    /* GDT index 260 */
-#define FLAT_RING1_SS 0x0821    /* GDT index 260 */
-#define FLAT_RING3_CS 0x082b    /* GDT index 261 */
-#define FLAT_RING3_DS 0x0833    /* GDT index 262 */
-#define FLAT_RING3_SS 0x0833    /* GDT index 262 */
+#define FLAT_RING1_CS 0xe019    /* GDT index 259 */
+#define FLAT_RING1_DS 0xe021    /* GDT index 260 */
+#define FLAT_RING1_SS 0xe021    /* GDT index 260 */
+#define FLAT_RING3_CS 0xe02b    /* GDT index 261 */
+#define FLAT_RING3_DS 0xe033    /* GDT index 262 */
+#define FLAT_RING3_SS 0xe033    /* GDT index 262 */
 
 #define FLAT_KERNEL_CS FLAT_RING1_CS
 #define FLAT_KERNEL_DS FLAT_RING1_DS
index 8e821688f7a5d7b85de02f43bd4b4b78d968b88c..c1a66992859d76f4fd52b0e3d17e812d459b5092 100644 (file)
  * A number of GDT entries are reserved by Xen. These are not situated at the
  * start of the GDT because some stupid OSes export hard-coded selector values
  * in their ABI. These hard-coded values are always near the start of the GDT,
- * so Xen places itself out of the way.
- * 
- * NR_RESERVED_GDT_ENTRIES is (8 + 4 * NR_CPUS) Please update this value if 
- * you increase NR_CPUS or add another GDT entry to gdt_table in boot/x86_64.S
- * 
- * NB. The reserved range is inclusive (that is, both FIRST_RESERVED_GDT_ENTRY
- * and LAST_RESERVED_GDT_ENTRY are reserved).
+ * so Xen places itself out of the way, at the far end of the GDT.
  */
-#define NR_RESERVED_GDT_ENTRIES    136
-#define FIRST_RESERVED_GDT_ENTRY   256
-#define LAST_RESERVED_GDT_ENTRY    \
-  (FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1)
+#define FIRST_RESERVED_GDT_PAGE  14
+#define FIRST_RESERVED_GDT_BYTE  (FIRST_RESERVED_GDT_PAGE * 4096)
+#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8)
 
 /*
  * 64-bit segment selectors
  * installing their own GDT.
  */
 
-#define FLAT_RING3_CS32 0x0823  /* GDT index 260 */
-#define FLAT_RING3_CS64 0x0833  /* GDT index 261 */
-#define FLAT_RING3_DS32 0x082b  /* GDT index 262 */
+#define FLAT_RING3_CS32 0xe023  /* GDT index 260 */
+#define FLAT_RING3_CS64 0xe033  /* GDT index 261 */
+#define FLAT_RING3_DS32 0xe02b  /* GDT index 262 */
 #define FLAT_RING3_DS64 0x0000  /* NULL selector */
-#define FLAT_RING3_SS32 0x082b  /* GDT index 262 */
-#define FLAT_RING3_SS64 0x082b  /* GDT index 262 */
+#define FLAT_RING3_SS32 0xe02b  /* GDT index 262 */
+#define FLAT_RING3_SS64 0xe02b  /* GDT index 262 */
 
 #define FLAT_KERNEL_DS64 FLAT_RING3_DS64
 #define FLAT_KERNEL_DS32 FLAT_RING3_DS32